\section*{Aclaraciones}

El int\'erprete utilizado para la realizaci\'on del TP fue Pharo.

\section*{Ejercicio 1}

\subsection*{Clase Celda}

\begin{lstlisting}[language=Smalltalk, numbers=left, numberstyle=\small]
Object subclass: #Celda
	instanceVariableNames: 'valor posicion'
	classVariableNames: ''
	poolDictionaries: ''
	category: 'TP-PLP-2011c1'
\end{lstlisting}

\subsubsection*{M\'etodos de clase}

\begin{lstlisting}[language=Smalltalk, numbers=left, numberstyle=\small]
crear: unaPosicion
	"crea una celda muerda en unaPosicion"
	^super new init: unaPosicion
\end{lstlisting}

\subsubsection*{M\'etodos de instancia}

\begin{lstlisting}[language=Smalltalk, numbers=left, numberstyle=\small]
init: unaPosicion
	"inicializa una celda muerta en unaPosicion"
	posicion := unaPosicion.
	valor := #muerta.
	^self
\end{lstlisting}

\begin{lstlisting}[language=Smalltalk, numbers=left, numberstyle=\small]
posicion
	^posicion
\end{lstlisting}

\begin{lstlisting}[language=Smalltalk, numbers=left, numberstyle=\small]
valor
	^valor
\end{lstlisting}

\begin{lstlisting}[language=Smalltalk, numbers=left, numberstyle=\small]
valor: nuevoValor
	"altera el valor  de la celda"
	((nuevoValor = #viva) | (nuevoValor = #muerta) ) 
		ifFalse: [Error new signal: 'Valor invalido: solo puede ser #viva o #muerta' ].  
	valor := nuevoValor.
	^self
\end{lstlisting}

%%% ************ FIN EJERCICIO 1 ****************

\section*{Ejercicio 2}

\subsection*{Clase Celda}

\subsubsection*{M\'etodos de instancia}

\begin{lstlisting}[language=Smalltalk, numbers=left, numberstyle=\small]
actualizarConVecinosVivos: cantVivos
	"calcula el nuevo valor segun las reglas tradicionales"
	valor := (MessageSend receiver: ActualizadorDeCelda selector: valor) value
		actualizarCon: cantVivos.    
	^self
\end{lstlisting}

\subsection*{Clase ActualizadorDeCelda}

\begin{lstlisting}[language=Smalltalk, numbers=left, numberstyle=\small]
Object subclass: #ActualizadorDeCelda
	instanceVariableNames: ''
	classVariableNames: ''
	poolDictionaries: ''
	category: 'TP-PLP-2011c1'
\end{lstlisting}

\subsubsection*{M\'etodos de clase}
\begin{lstlisting}[language=Smalltalk, numbers=left, numberstyle=\small]
actualizarCon: cantVecinos   
	"devuelve el nuevo valor para la celda si tiene un numero de vecinos igual a cantVecinos"
	| nuevoValor |
	(self viveCon: cantVecinos)
		ifTrue: [nuevoValor := #viva ] 
		ifFalse: [nuevoValor := #muerta ].  
	^nuevoValor
\end{lstlisting}

\begin{lstlisting}[language=Smalltalk, numbers=left, numberstyle=\small]
muerta
	"devuelve la subclase correspondiente"
	^ActualizadorDeCeldaMuerta
\end{lstlisting}

\begin{lstlisting}[language=Smalltalk, numbers=left, numberstyle=\small]
viva
	"devuelve la subclase correspondiente"
	^ActualizadorDeCeldaViva 
\end{lstlisting}

\begin{lstlisting}[language=Smalltalk, numbers=left, numberstyle=\small]
viveCon: cantVecinos
	"devuelve un Boolean que indica si la celda permanece/pasa a estar viva
	con un numero de vecinos igual a cantVecinos"
	^self subclassResponsibility 
\end{lstlisting}

\subsection*{Clase ActualizadorDeCeldaViva}

\begin{lstlisting}[language=Smalltalk, numbers=left, numberstyle=\small]
ActualizadorDeCelda subclass: #ActualizadorDeCeldaViva
	instanceVariableNames: ''
	classVariableNames: ''
	poolDictionaries: ''
	category: 'TP-PLP-2011c1'
\end{lstlisting}

\subsubsection*{M\'etodos de clase}
\begin{lstlisting}[language=Smalltalk, numbers=left, numberstyle=\small]
viveCon: cantVecinos   
	"implementa el metodo de la clase base"
	^((cantVecinos == 2) | (cantVecinos == 3))
\end{lstlisting}


\subsection*{Clase ActualizadorDeCeldaMuerta}
\begin{lstlisting}[language=Smalltalk, numbers=left, numberstyle=\small]
ActualizadorDeCelda subclass: #ActualizadorDeCeldaMuerta
	instanceVariableNames: ''
	classVariableNames: ''
	poolDictionaries: ''
	category: 'TP-PLP-2011c1'
\end{lstlisting}

\subsubsection*{M\'etodos de clase}
\begin{lstlisting}[language=Smalltalk, numbers=left, numberstyle=\small]
viveCon: cantVecinos   
	"implementa el metodo de la clase base"
	^(cantVecinos == 3)
\end{lstlisting}

%%% ************ FIN EJERCICIO 2 ****************

\section*{Ejercicio 3}

\subsection*{Clase Grilla}

\begin{lstlisting}[language=Smalltalk, numbers=left, numberstyle=\small]
Object subclass: #Grilla
	instanceVariableNames: 'celdas'
	classVariableNames: ''
	poolDictionaries: ''
	category: 'TP-PLP-2011c1'
\end{lstlisting}

\subsubsection*{M\'etodos de clase}
\begin{lstlisting}[language=Smalltalk, numbers=left, numberstyle=\small]
de: cantFilas por: cantColumnas
	"crea una grilla con celdas muertas"
	^super new iniFilas: cantFilas iniColumnas: cantColumnas   
\end{lstlisting}

\subsubsection*{M\'etodos de instancia}

\begin{lstlisting}[language=Smalltalk, numbers=left, numberstyle=\small]
iniFilas: filas iniColumnas: columnas
	"inicializa con esas cantidades de filas y columnas"
	celdas := Matrix rows: filas columns: columnas.
	celdas indicesDo: [:r :c | celdas at: r at: c put: (Celda crear: (r@c)) ].
	^self   
\end{lstlisting}

\begin{lstlisting}[language=Smalltalk, numbers=left, numberstyle=\small]
filas
	^celdas rowCount
\end{lstlisting}

\begin{lstlisting}[language=Smalltalk, numbers=left, numberstyle=\small]
columnas
	^celdas columnCount
\end{lstlisting}

\begin{lstlisting}[language=Smalltalk, numbers=left, numberstyle=\small]
ponerViva: unaPosicion
	"pone la celda indicada como viva"
	(celdas at: unaPosicion x at: unaPosicion y) valor: #viva.
	^self
\end{lstlisting}

\begin{lstlisting}[language=Smalltalk, numbers=left, numberstyle=\small]
printString
	"Devuelve un string con el contenido de la grilla"
	| s |
	s := String new.
	celdas do: 	[:celda | |p| p:=celda posicion. s := s, 
		celda valor printString ,'  '. 
		(p y == celdas columnCount) ifTrue: [s:=s, String cr] ].
	^s
\end{lstlisting}

%%% ************ FIN EJERCICIO 3 ****************

\section*{Ejercicio 4}

\subsection*{Clase Grilla}

\subsubsection*{M\'etodos de instancia}

\begin{lstlisting}[language=Smalltalk, numbers=left, numberstyle=\small]
celdasVecinas: unaPosicion
	"devuelve un conjunto de celdas vecinas a la posicion dada"
	| v x y p |
	x := unaPosicion x.
	y := unaPosicion y.
	v := LinkedList new. "para los vecinos"
	(x-1 max: 1) to: (x+1 min: celdas rowCount) do: [:r |
		(y-1 max: 1) to: (y+1 min: celdas columnCount) do: [:c |
			p := (r@c). (p = unaPosicion) ifFalse: [v add: p] ] ].
	^v
\end{lstlisting}

\begin{lstlisting}[language=Smalltalk, numbers=left, numberstyle=\small]
avanzar
	"aplica una iteracion de las reglas a todas las celdas"
	| copias vivos |
	"la copia:"
	copias := Matrix rows: celdas rowCount columns: celdas columnCount.
	celdas withIndicesDo: [:elem :r :c| copias at: r at: c put: (elem copy) ]. 	
	"la aplicacion:"
	celdas with: copias do: [ :celda :copia | 
		vivos := 0. "para contar los vecinos vivos"
		(self celdasVecinas: celda posicion ) do:
			[ :p | (celdas at: p x at: p y) valor = #viva ifTrue:[ vivos := vivos + 1]  ].
		copia actualizarConVecinosVivos: vivos.
		].
	celdas := copias.
	^self  
\end{lstlisting}

\subsection*{Clase Celda}

\subsubsection*{M\'etodos de instancia}

\begin{lstlisting}[language=Smalltalk, numbers=left, numberstyle=\small]
copy
	"devuelve una copia de la instancia"
	^(Celda crear: posicion copy) valor: valor
\end{lstlisting}

%%% ************ FIN EJERCICIO 4 ****************

\section*{Ejercicio 5}

\subsection*{Clase Juego}
\begin{lstlisting}[language=Smalltalk, numbers=left, numberstyle=\small]
Object subclass: #Juego
	instanceVariableNames: 'grilla'
	classVariableNames: ''
	poolDictionaries: ''
	category: 'TP-PLP-2011c1'
\end{lstlisting}

\subsubsection*{M\'etodos de clase}
\begin{lstlisting}[language=Smalltalk, numbers=left, numberstyle=\small]
crearDe: cantFilas por: cantColumnas
	"Crea un juego nuevo con una grilla de cantFilas x cantColumnas"
	^super new iniFilas: cantFilas iniColumnas: cantColumnas
\end{lstlisting}

\subsubsection*{M\'etodos de instancia}

\begin{lstlisting}[language=Smalltalk, numbers=left, numberstyle=\small]
iniFilas: filas iniColumnas: columnas
	"inicializa con esas cantidades de filas y columnas"
	grilla := Grilla de: filas por: columnas.
	^self   
\end{lstlisting}

\begin{lstlisting}[language=Smalltalk, numbers=left, numberstyle=\small]
grilla
	"Devuelve la grilla actual"
	^grilla
\end{lstlisting}

\begin{lstlisting}[language=Smalltalk, numbers=left, numberstyle=\small]
avanzar
	"Realiza una evolucion de la grilla actual e imprime el resultado"
	grilla avanzar.
	Transcript show: grilla printString .
	^self.
\end{lstlisting}

\begin{lstlisting}[language=Smalltalk, numbers=left, numberstyle=\small]
ponerViva: posicion  
	"Pone una celda viva en la posicion indicada"
	grilla ponerViva: posicion.
	^self  
\end{lstlisting}

\begin{lstlisting}[language=Smalltalk, numbers=left, numberstyle=\small]
ponerBlock: posicionInicial
	"Pone un block comenzando en la posicion especificada. Si no hay lugar, deja la grilla como esta"
	| p1 p2 p3|
	p1 := posicionInicial + (1@1) .
	p2 := posicionInicial + (1@0) .
	p3 := posicionInicial + (0@1) .
	^self ponerVivas: (Array with: posicionInicial with: p1 with: p2 with: p3).  
\end{lstlisting}

\begin{lstlisting}[language=Smalltalk, numbers=left, numberstyle=\small]
ponerBlinker: posicionInicial
	"Pone un blinker comenzando en la posicion especificada. Si no hay lugar, deja la grilla como esta"
	| p1 p2 |
	p1 := posicionInicial + (0@(-1)).
	p2 := posicionInicial + (0@1).
	^self ponerVivas: (Array with: posicionInicial with: p1 with: p2). 
\end{lstlisting}

\begin{lstlisting}[language=Smalltalk, numbers=left, numberstyle=\small]
ponerVivas: posiciones
	"Pone como vivas todas las posiciones de la coleccion posiciones"
	|validas|
	validas:=true.
	posiciones do: [:pos | validas:=validas & (grilla posicionValida:  pos) ].
	(validas) ifTrue: [posiciones do: [:pos | grilla ponerViva: pos  ]].
	^self . 
\end{lstlisting}

\subsection*{Clase Grilla}

\subsubsection*{M\'etodos de instancia}

\begin{lstlisting}[language=Smalltalk, numbers=left, numberstyle=\small]
posicionValida: posicion
	"Devuelve true si la posicion se encuentra dentro de las dimensiones de la grilla"
	|x y ancho alto|
	ancho := celdas columnCount.
	alto := celdas rowCount.
	x := posicion x.
	y := posicion y.
	^((x > 0) & (x <= alto) & (y > 0) & (y <= ancho))
\end{lstlisting}
